package com.xgxx.hy.library.admin.dingtalk.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import com.xgxx.hy.library.admin.common.config.DingTalkConfig;
import com.xgxx.hy.library.admin.common.constant.R;
import com.xgxx.hy.library.admin.dingtalk.entity.DingTalkDeptRet;
import com.xgxx.hy.library.admin.dingtalk.entity.DingTalkUserDetail;
import com.xgxx.hy.library.admin.dingtalk.entity.DingTalkUserDetailRet;
import com.xgxx.hy.library.admin.dingtalk.entity.DingTalkUserRet;
import com.xgxx.hy.library.admin.dingtalk.service.IDingtalkService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author liwt
 * @version V2.4.0
 * @date 2021年10月22日 9:19
 * @Copyright:2021 徐工信息 All rights reserved.
 */
@Slf4j
@Service
public class DingtalkServiceImpl implements IDingtalkService {

    private static final String DINGTALK_RET_SUCCESS = "0";

    @Autowired
    private DingTalkConfig dingTalkConfig;

    @Override
    public R<String> sendMsg(String userMobile, String msgContent) {
        if (StrUtil.isBlank(userMobile) || StrUtil.isBlank(msgContent)) {
            return R.fail("接收人手机号和消息内容不能为空");
        }
        R<String> ret1 = this.refreshAccessToken();
        if (!ret1.isSuccess()) {
            return ret1;
        }
        String accesToken = ret1.getData();
        R<String> ret2 = this.getDingtalkUserId(userMobile, accesToken);
        if (!ret2.isSuccess()) {
            return ret2;
        }
        String dingtalkUserId = ret2.getData();
        return this.sendDingtalkMsg(dingtalkUserId, msgContent, accesToken);
    }

    @Override
    public R<DingTalkUserDetail> dingtalkUserDetail(String userMobile) {
        if (StrUtil.isBlank(userMobile)) {
            return R.fail("接收人手机号不能为空");
        }
        R<String> ret1 = this.refreshAccessToken();
        if (!ret1.isSuccess()) {
            return R.fail(ret1.getMsg());
        }
        String accesToken = ret1.getData();
        R<String> ret2 = this.getDingtalkUserId(userMobile, accesToken);
        if (!ret2.isSuccess()) {
            return R.fail(ret2.getMsg());
        }
        String dingtalkUserId = ret2.getData();
       return this.getDingTalkUserDetail(dingtalkUserId,accesToken);
    }

    private R<DingTalkUserDetail> getDingTalkUserDetail(String dingtalkUserId, String accesToken) {
        R<String> ret3 = this.getDingtalkUserDetail(dingtalkUserId, accesToken);
        if (!ret3.isSuccess()) {
            return R.fail(ret3.getMsg());
        }
        DingTalkUserDetailRet detailRet = JSONUtil.toBean(ret3.getData(), DingTalkUserDetailRet.class);
        if (DINGTALK_RET_SUCCESS.equals(detailRet.getErrcode())) {
            DingTalkUserDetail userDetail = detailRet.getResult();
            List<String> deptIdList = userDetail.getDept_id_list();
            if (CollectionUtil.isNotEmpty(deptIdList)) {
                R<String> deptRet = this.getDeptDetail(deptIdList.get(0), accesToken);
                if (deptRet.isSuccess()) {
                    userDetail.setDeptName(deptRet.getData());
                }
            }
            return R.data(userDetail);
        } else {
            return R.fail(detailRet.getErrmsg());
        }
    }

    @Override
    public R<DingTalkUserDetail> login(String requestAuthCode) {
        // 获取用户信息
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/getuserinfo");
        OapiUserGetuserinfoRequest request = new OapiUserGetuserinfoRequest();
        request.setCode(requestAuthCode);
        request.setHttpMethod("GET");
        OapiUserGetuserinfoResponse response;
        R<String> ret1 = this.refreshAccessToken();
        if (!ret1.isSuccess()) {
            return R.fail(ret1.getMsg());
        }
        String accesToken = ret1.getData();
        try {
            response = client.execute(request, accesToken);
        } catch (ApiException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return R.fail("");
        }
        // 查询得到当前用户的userId
        // 获得到userId之后应用应该处理应用自身的登录会话管理（session）,避免后续的业务交互（前端到应用服务端）每次都要重新获取用户身份，提升用户体验
        String dingtalkUserId = response.getUserid();

        if (StrUtil.isBlank(dingtalkUserId)) {
            return R.fail("未找到当前登录人信息");
        }
        return this.getDingTalkUserDetail(dingtalkUserId,accesToken);
    }

    private R<String> refreshAccessToken() {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            OapiGettokenRequest request = new OapiGettokenRequest();
            request.setAppkey(dingTalkConfig.getAppKey());
            request.setAppsecret(dingTalkConfig.getAppSecret());
            request.setHttpMethod("GET");
            OapiGettokenResponse response = client.execute(request);
            String access_token = response.getAccessToken();
            return R.data(access_token);
        } catch (Exception e) {
            log.error(e.getMessage());
            return R.fail("请求AccessToken报错");
        }
    }

    private R<String> getDingtalkUserId(String userMobile, String access_token) {
        try {
            DingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserUseridGetbymobileRequest req = new OapiV2UserUseridGetbymobileRequest();
            req.setMobile(userMobile);
            OapiV2UserUseridGetbymobileResponse rsp = client2.execute(req, access_token);
            if (rsp.isSuccess()) {
                DingTalkUserRet dingTalkUserRet = JSON.parseObject(rsp.getBody(), DingTalkUserRet.class);
                return R.data(dingTalkUserRet.getResult().getUserid());
            } else {
                return R.fail("获取用户ID失败");
            }
        } catch (Exception e) {
            log.error(e.getMessage());
            return R.fail("获取用户ID失败");
        }
    }

    private R<String> sendDingtalkMsg(String userIdList, String content, String accessToken) {
        try {
            log.debug("userIdList:" + userIdList);
            log.debug("content:" + content);
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
            OapiMessageCorpconversationAsyncsendV2Request req = new OapiMessageCorpconversationAsyncsendV2Request();
            req.setAgentId(Long.valueOf(this.dingTalkConfig.getAgentId()));
            req.setUseridList(userIdList);
            req.setMsg(content);
            OapiMessageCorpconversationAsyncsendV2Request.Msg obj1 = new OapiMessageCorpconversationAsyncsendV2Request.Msg();
            obj1.setMsgtype("text");
            OapiMessageCorpconversationAsyncsendV2Request.Text obj2 = new OapiMessageCorpconversationAsyncsendV2Request.Text();
            obj2.setContent(content);
            obj1.setText(obj2);
            req.setMsg(obj1);
            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(req, accessToken);
            log.debug(rsp.getBody());
            if (rsp.isSuccess()) {
                return R.data(String.valueOf(rsp.getTaskId()));
            } else {
                return R.fail(rsp.getErrmsg());
            }
        } catch (ApiException e) {
            log.error(e.getMessage());
            return R.fail("发送钉钉消息异常:" + e.getErrMsg());
        }
    }

    private R<String> getDingtalkUserDetail(String userId, String accessToken) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.setUserid(userId);
            OapiV2UserGetResponse rsp = client.execute(req, accessToken);
            return R.data(rsp.getBody());
        } catch (ApiException e) {
            e.printStackTrace();
            return R.fail("获取用户详细信息异常");
        }
    }

    private R<String> getDeptDetail(String deptId, String accessToken) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/get");
            OapiDepartmentGetRequest req = new OapiDepartmentGetRequest();
            req.setId(deptId);
            req.setHttpMethod("GET");
            OapiDepartmentGetResponse rsp = client.execute(req, accessToken);
            DingTalkDeptRet deptRet = JSONUtil.toBean(rsp.getBody(), DingTalkDeptRet.class);
            if (DINGTALK_RET_SUCCESS.equals(deptRet.getErrcode())) {
                return R.data(deptRet.getName());
            } else {
                return R.fail(deptRet.getErrmsg());
            }
        } catch (Exception e) {
            e.printStackTrace();
            return R.fail("获取部门详情失败:" + e.getMessage());
        }
    }
}


